Prop Controller, randomness....

Ok, so, I switched from programming in Arduino C++ to BASIC and now back… huh, what is that? I know I’m confused as well. I have read quite a bit of documentation but I’m still having issues. OK, so, I just want to build a simple prop controller for Halloween. One PIR sensor on input 3, runs the code. Triggers Prop 1 after 3 seconds for a random amount of time up until 25 seconds. Prop 2 goes off “randomly” between 25 seconds and 30 seconds for 2 seconds. Then Prop 3 may or may not go off for a random 10 to 20 seconds at the end.

The PIRSENSE code was a lot to take in but I think I have broken it down… the random function isn’t working like I expect it to. Should I be using Millis?

Here is my code/copy paste stuff so far.

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;  
long unsigned int lowIn;         //the time when the sensor outputs a low impulse
long unsigned int pause = 5000;  //the amount of milliseconds the sensor has to be low 
                                 //before we assume all motion has stopped
boolean lockLow = true;
boolean takeLowTime;  
int pirPin = 3;    //the digital pin connected to the PIR sensor's output
int PROP1 = A1;
int PROP2 = A2;
int PROP3 = A3;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(PROP1, OUTPUT);
  pinMode(PROP2, OUTPUT);
  pinMode(PROP3, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop(){

     if(digitalRead(pirPin) == HIGH){
          delay (3000);
       digitalWrite(PROP1, HIGH);   //the led visualizes the sensors output pin state
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;
         delay (300);            
         random (20000,25000);
         digitalWrite(PROP1, LOW);
         random (26000, 29000);
         digitalWrite(PROP2, HIGH);
         delay (300);
         random (32000, 35000);
         digitalWrite(PROP2, LOW);
         delay (10000);
         digitalWrite(PROP3, HIGH);
         delay (300);
         random (38000, 46000);
         digitalWrite(PROP3, LOW);
         }         
         takeLowTime = true;
       }
       

     if(digitalRead(pirPin) == LOW){       
      

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           delay(50);
           }
       }
       if(digitalRead(pirPin) == HIGH){
        
       digitalWrite(PROP1, HIGH); //the led visualizes the sensors output pin state
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         delay(50);
         }         
         takeLowTime = true;
       }
       

     if(digitalRead(pirPin) == LOW){       
       digitalWrite(PROP1, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           delay(50);
           return;
           }
       }
  }

To clarify: With only one input (PIRSENSOR) I would like PROP1 to be a constant that starts randomly between 3 to 5 seconds for a random 15 to 25 or so seconds. PROP2 may or may not go off for 2 seconds, 30 seconds into the routine. PROP 3 may or may not go off for 10 to 20 seconds at the end.

random (20000,25000);

If you don't do something with the random number (such as assign it to a variable), then nothing useful happens. Try something like this instead:

long waitTime = random(20000, 25000); // assign the random number to a variable
delay(waitTime); // use the number

Perfect, it works great. Thank you so much for the guidance. The last thing is I want PROP2 and PROP3 to may or may not go off. PROP1 always goes off, PROP2 May or may not, and PROP3 May or may not go off. Sometime they both go off at the same time sometimes only one and sometimes neither.

MrMetro: Perfect, it works great. Thank you so much for the guidance. The last thing is I want PROP2 and PROP3 to may or may not go off. PROP1 always goes off, PROP2 May or may not, and PROP3 May or may not go off. Sometime they both go off at the same time sometimes only one and sometimes neither.

Then get another random number, and use an if statement, or maybe a switch statement, based on what that random number is.

Nothing gripes me more then researching code and someone says they got it working… and don’t post the code. So, Here it is, it is very close and may need a little more tweaking/clean up.

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;  
long unsigned int lowIn;         //the time when the sensor outputs a low impulse
long unsigned int pause = 5000;  //the amount of milliseconds the sensor has to be low 
                                //before we assume all motion has stopped
boolean lockLow = true;
boolean takeLowTime;  
int pirPin = 3;    //the digital pin connected to the PIR sensor's output
int PROP1 = 7;
int PROP2 = 8;
int PROP3 = 9
;

long waitTime = random(15000, 20000); // assign the random number to a variable
long waitTime1 = random(7000, 15000);
long waitTime2 = random(0, 3000);

int ranNum;
int ranDel;

/////////////////////////////
//SETUP
void setup(){
 Serial.begin(9600);
 pinMode(pirPin, INPUT);
 pinMode(PROP1, OUTPUT);
 pinMode(PROP2, OUTPUT);
 pinMode(PROP3, OUTPUT);
 digitalWrite(pirPin, LOW);
randomSeed(analogRead(0));

 //give the sensor some time to calibrate
 Serial.print("calibrating sensor ");
   for(int i = 0; i < calibrationTime; i++){
     Serial.print(".");
     delay(1000);
     }
   Serial.println(" done");
   Serial.println("SENSOR ACTIVE");
   delay(50);
 }

////////////////////////////
//LOOP
void loop(){

    if(digitalRead(pirPin) == HIGH){
         delay (3000);
      digitalWrite(PROP1, HIGH);   //the led visualizes the sensors output pin state
      if(lockLow){       //makes sure we wait for a transition to LOW before any further output is made:
        lockLow = false;
        delay  (waitTime);
        digitalWrite(PROP1, LOW);
        delay  (waitTime1);
        ranNum=random(8, 10);
        ranDel=random(0, 3000);
        digitalWrite(ranNum, HIGH);
        delay(ranDel);
        digitalWrite(ranNum,LOW);
        delay (45000);
        }         
        takeLowTime = true;
      }
      

    if(digitalRead(pirPin) == LOW){       
     

      if(takeLowTime){
       lowIn = millis();          //save the time of the transition from high to LOW
       takeLowTime = false;       //make sure this is only done at the start of a LOW phase
       }
      //if the sensor is low for more than the given pause, 
      //we assume that no more motion is going to happen
      if(!lockLow && millis() - lowIn > pause){  
          //makes sure this block of code is only executed again after 
          //a new motion sequence has been detected
          lockLow = true;                        
          Serial.print("motion ended at ");      //output
          Serial.print((millis() - pause)/1000);
          Serial.println(" sec");
          delay(50);
          }
      }
      if(digitalRead(pirPin) == HIGH){
       
      digitalWrite(PROP1, HIGH); //the led visualizes the sensors output pin state
      if(lockLow){  
        //makes sure we wait for a transition to LOW before any further output is made:
        lockLow = false;            
        Serial.println("---");
        Serial.print("motion detected at ");
        Serial.print(millis()/1000);
        Serial.println(" sec"); 
        delay(50);
        }         
        takeLowTime = true;
      }
      

    if(digitalRead(pirPin) == LOW){       
      digitalWrite(PROP1, LOW);  //the led visualizes the sensors output pin state

      if(takeLowTime){
       lowIn = millis();          //save the time of the transition from high to LOW
       takeLowTime = false;       //make sure this is only done at the start of a LOW phase
       }
      //if the sensor is low for more than the given pause, 
      //we assume that no more motion is going to happen
      if(!lockLow && millis() - lowIn > pause){  
          //makes sure this block of code is only executed again after 
          //a new motion sequence has been detected
          lockLow = true;                        
          Serial.print("motion ended at ");      //output
          Serial.print((millis() - pause)/1000);
          Serial.println(" sec");
          delay(50);
          return;
          }
      }
 }