Need help cleaning up some code to use to launch multiple videos

Hi, I'm trying to use arduino with some PIR sensors to launch videos stored on my PC by coupling the arduino code with some simple python code.

Anyway I'm having trouble launching the second video (hoping to launch alot more than that with ultrasonics at different distances, but I digress) as my knowledge of coding is pretty basic. I think I've just confused the heck out of myself by trying to shove in a 'do while' loop to remedy my previous attempt at the triggering which only worked with one video.

The 'OBJECT' isn't getting detected by my second PIR but I'm pretty sure I have them hooked up right and the PIR definitely works as I tested it with the code I modified from an email sending PIR code I blatantly borrowed.

Here's the code

int pirPin1 = 7;
int pirPin2 = 8;

int minSecsBetweenVidlaunch = 60; // 1 min

long lastSend = -minSecsBetweenVidlaunch * 1000l;

void setup()
{
 Serial.begin(9600);
 pinMode(pirPin1, INPUT);
 pinMode(pirPin2, INPUT);
}

void loop()
{
 long now = millis();
 if (digitalRead(pirPin1) == HIGH)
 {
 if (now > (lastSend + minSecsBetweenVidlaunch * 1000l))
  {
   Serial.println("MOVEMENT");
   lastSend = now;
  }
  else
  {
   Serial.println("Too soon");
  }
 }
 delay(500);
 }
 do {
  Serial.println("OBJECT");
 } while (digitalRead(pirPin2) == HIGH)
}

It doesn't work and I'm confused you guys, please offer some guidance.
Thanks in advance, I've tried to abide by the forum rules.

Guidance:

Always used 'unsigned long' variables with millis().

Always use (currentMillis - millisAtStartOfInterval) compared to lengthOfInterval to see if an interval has elapsed.

You have one block of code that you want to run for each sensor. If you put the PIR pin numbers in an array then you can run that block of code for each sensor in turn, not caring how many sensors there are to read.

Mind johnwasser's guidance on the time checking and change the variables that have to do with time to unsigned longs.

Below code demonstrates what I mean about using arrays.

int pirPin1 = 7;
int pirPin2 = 8;

int pirPins[] = {7, 8};   // pins for all sensors

int minSecsBetweenVidlaunch = 60; // 1 min

long lastSend = -minSecsBetweenVidlaunch * 1000l;

void setup()
{
  Serial.begin(9600);
  pinMode(pirPin1, INPUT);
  pinMode(pirPin2, INPUT);
}

void loop()
{
  long now = millis();

  // while more sensors
  for (int i = 0; i < sizeof(pirPins) / sizeof(pirPins[0]); i++)
  {

    if (digitalRead(pirPins[i]) == HIGH)
    {
      if (now > (lastSend + minSecsBetweenVidlaunch * 1000l))
      {
        Serial.println("MOVEMENT");
        lastSend = now;
      }
      else
      {
        Serial.println("Too soon");
      }
    }
    delay(500);

  } // for

}

The 'OBJECT' isn't getting detected by my second PIR

What 'OBJECT' are you trying to detect? PIR sensors only sense warm bodies moving.

You need to take a look at the state change detection example. You want to do something when the PIR sensor detects that motion has started, NOT when the sensor reports that motion is happening.

You do NOT want to use addition with unsigned long time values. That can cause rollover. Subtraction handles one variable having rolled over. Always use subtraction. Now minus then may, or may not, exceed some interval.

It is almost never necessary to use do/while loops. While loops are useful, but I doubt that that is what you want to do in this case.

Thanks a lot for your help, I shall use your suggestions in my new sketch and get back to you over the weekend with my successes or my failures. I really appreciate it, oh and yes 'OBJECT' was technically wrong but it was just a quick thought to change it to something else for the other pin. Maybe 'WARMBLOODEDMAMMAL' would have been sufficient :slight_smile:

Sorry I took so long to get back here, am busy working most of the time.
Peace

Hey, I've cleaned up the code a little using your help but require to have pins called from the python program using an index so the '"MOVEMENT " needs to be numbered according to pin number which is what I've tried to do here but it doesn't work. I need "i" to be the pirPin number

Also if I'm declaring the pirPins in an array now I don't need the pirPin1 and pirPin2 in the setup anymore or do I still need it? I assume I can just use the array in the setup?
As in

void setup()
{
 Serial.begin(9600);
 pinMode(pirPins[], INPUT);
}

Or something like that?
Anyway here's the new code that kinda works but is not doing what I would like it to.

int pirPin1 = 7;
int pirPin2 = 8;

int pirPins[] = {7, 8};   // pins for all sensors

int minSecsBetweenVidlaunch = 60; // 1 min

unsigned long lastSend = -minSecsBetweenVidlaunch * 1000l;

void setup()
{
 Serial.begin(9600);
 pinMode(pirPin1, INPUT);
 pinMode(pirPin2, INPUT);
}

void loop()
{
 unsigned long now = millis();
 
 for (int i = 0; i < sizeof(pirPins) / sizeof(pirPins[0]); i++)
  {
    if (digitalRead(pirPins[i]) == HIGH)
    {
      if (now > (lastSend + minSecsBetweenVidlaunch * 1000l))
      {
        Serial.print("MOVEMENT ");
        Serial.print(i);
        Serial.println('/n');
        lastSend = now;
      }
      else
      {
        Serial.println("Too soon");
      }
    }
    delay(500);

  } // for
}

Thanks again for your reply's, I really appreciate your time.

I assume I can just use the array in the setup?

No.The pinMode() function does not take an array. You can use a for loop to iterate over the array, though.

Hey there, am back again with a few questions.

The code only seems to read one of the sensors, why is this do you think? I know what I need is for the sketch to read both sensors and print the number of each pin (either 7 or 8 in this case but maybe more if possible) accordingly (i.e. MOVEMENT 7 or MOVEMENT 8 - even MOVEMENT 0 or MOVEMENT 1 would do as it is just being read by the ser.readline in a python program where it will launch an video in vlc all going to plan).

I need each sensor to launch a separate video and hopefully learning from this figure out how to manipulate ultrasonic sensors to do similar yet more complex tasks (i.e. launch a video when in range of detection but change the video when at a certain distance to the sensor hidden beneath the screen)

So the code I have at the moment doesn't print what I need it to to the serial monitor and so will not be compatible with my little python program. Any advice would be appreciated, I can see you don't want to spoonfeed and I am enjoying learning but my time is limited. So if I can manipulate this if statement in the for loop do i need to declare another integer to hold the values i need to increment and print to the serial monitor

for (int i = 0; i < sizeof(pirPins) / sizeof(pirPins[0]); i++)
  {
    if (digitalRead(pirPins[i]) == HIGH)
    {
      if (now > (lastSend + minSecsBetweenVidlaunch * 1000l))
      {
        Serial.print("MOVEMENT ");
        Serial.print(sizeof(pirPins[i]));
        Serial.println();
        lastSend = now;
      }
      else
      {
        Serial.println("Too soon");
      }
    }
    delay(500);
  }

I know it's wrong but it prints it out in the way I need it to and I just looked at way too much code I don't understand and am hyper-confused. Thanks

Once you read a pin, and send data for that pin, you can't send any data for any other pins until minSecsBetweenVidlaunch * 1000l milliseconds have elapsed.

First, I really hate to see lower case L used for the type modifier. Too hard to distinguish from a 1. An upper case L does the same thing, but is far easier to distinguish.

Second, I think you want an array of lastSend values, so you can keep track of when you send messages for each pin.

OK so you mean minSecsBetweenVidlaunch * 1000L, yea I agree. Seeing as I "borrowed" the code I hadn't even realized that because of my terrible on again off again coding where I never fully grasp what the feck I'm doing.

So you're saying nest another if statement within the for loop to keep track of lastSend which will help in what way exactly?

Feel free to tell me to figure it out for myself, any answer is appreciated and will add to my beautiful frustration.

Suppose you are to meet your mother for dinner in3 hours, your brother for drinks in 2 hours, and your girlfriend for fun and games in one hour. Can you set one timer to make sure you get each place on time?

No, you need three timers.

You are trying to use one value to define the last time you dealt with however many different pins there are. If sizeof(pirPins) / sizeof(pirPins[0] is 1. that will work. For any other value, it won't. You need an array of lastTime's just like you have an array of pin numbers. The last time you dealt with the 0th pin has nothing to do with the last time you dealt with the 1st pin or the 2nd pin or the 3rd pin or the nth pin.

Thanks Paul, am still digesting your information and getting to grips with timer and array functionality. Just one other question, so the for loop is just an example of an incrementing array I just threw in there not knowing what I'm doing. What I really need is to be able to distinguish between the two pins in the output to the serial monitor. This means the code

if (digitalRead(pirPins*) == HIGH)*
means it doesn't matter which PIR is being triggered, it will print MOVEMENT?
Thanks again

This means the code

if (digitalRead(pirPins) == HIGH)

means it doesn't matter which PIR is being triggered, it will print MOVEMENT?

There is a reason that ALL code goes in code tags.

Oh, sorry

if (digitalRead(pirPins) == HIGH)

entheogen:
Oh, sorry

if (digitalRead(pirPins) == HIGH)

pirPins is an array. You can't digitalRead() a whole array of pins.