Multiple function work simultaneously

Please I need some help… How can I make my PIR function to work simultaneously with my two led’s blinking without intercepting each other… The PIR function operates the same time as the led’s blink. Here is my program: (plus i’ve done the millis(); thing, but i dont know where to put it in the PIR function){PIR=motion sensor}

int pirpin=8, pirled=9, pirrelay=33, calibrationTime=15, pir;
int led1=18, led2=20;
void setup(){
pinMode(pirpin, INPUT);
pinMode(pirled, OUTPUT);
pinMode(pirrelay, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
}
void loop(){
pirv();
digitalWrite(led1, HIGH);
delay(1000);
digitalWrite(led1, LOW);
delay(1000);
digitalWrite(led2, HIGH);
delay(1000);
digitalWrite(led2, LOW);
delay(1000);
}
void pirv(){
pir=digitalRead(pirpin);
if(pir==HIGH)
{delay(1000);
if(pir==HIGH){
for(int x=0; x<5;x++)
{
digitalWrite(pirled,HIGH);
digitalWrite(pirrelay,HIGH);
delay(1000);
if(digitalRead(pirpin)==HIGH)
{
x=0;
}
}
digitalWrite(pirled, LOW);
digitalWrite(pirrelay, LOW);
}
}
}

Thank you…

Get rid of the delay() functions and embrace the example sketch Blink Without Delay. (Insert gospel choir Ahhh)

I've removed my delay() functions in the pirv(), but i don't know where to put the millis() function just like in BlinkWithoutDelay example, plus i don't how much time would I put for the intervals because its a motion sensor, I program it to scan for motion for every one second. I am also a beginner for programming in arduino. I appreciate your help. Thanks :)

http://gammon.com.au/blink

First take out All the delays, second get one LED to blink, then get both to blink, finally add the sensor. Work on things individually, and not as a whole, it will drive you crazy if you do.

I know Nick Gammon has some good examples and also Robin2 has some as well.

Edit: ha, Nick already replied.

Now it's my turn :) See the demo several things at a time

...R

Compared to the program above and the program that I’ve made now, the operation are now working simultaneously, Thank you very much, I take out my delay() functions in the pirv() function. The problem now is that the detection operation of my motion sensor is not accurate, suppose to be from the previous program, I must scan motion every 1 second and it will always have an output of HIGH, then when there is no motion, after 5 sec it will signals LOW, I am using a Mini PIR sensor with no adjustable knob(attached file), what should I do? By the way, LED blinking must stay in the void loop() function only the pirv() funtion must synchronize to the LED’s. I’m still new for this kind of programming skills.THANK YOU :slight_smile:

Program:
int pirpin=8, pirled=9, pirrelay=33, calibrationTime=15, pir;
int led1=18, led2=20;
byte pirstate = LOW;
unsigned long current = 0;
unsigned long previous = 0;
unsigned long on = 5000;
unsigned long duration = 5000;
void setup(){
pinMode(pirpin, INPUT);
pinMode(pirled, OUTPUT);
pinMode(pirrelay, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
}
void loop(){
pirv();
output();
digitalWrite(led1, HIGH);
delay(1000);
digitalWrite(led1, LOW);
delay(1000);
digitalWrite(led2, HIGH);
delay(1000);
digitalWrite(led2, LOW);
delay(1000);
}
void pirv(){
current = millis();
if(pirstate==LOW){
if(current - previous >= on);{
previous += on;
if(digitalRead(pirpin)==HIGH){
pirstate = HIGH;
}
}
}
else{
if(current - previous >= duration){
previous += duration;
if(digitalRead(pirpin)==LOW){
pirstate=LOW;
}
}
}
}
void output(){
digitalWrite(pirled, pirstate);
digitalWrite(pirrelay, pirstate);
}

mini pir sensor.jpg

you can try something like this, which flashed them alternating, not quite what you are doing in your loop() function but hopefully you get the point.

not tested, but compiles:

int pirpin=8, pirled=9, pirrelay=33, calibrationTime=15, pir;
int led1=18, led2=20;
byte pirstate = LOW;
unsigned long current = 0;
unsigned long previous = 0;
unsigned long on = 5000;
unsigned long duration = 5000;


void setup()
{
  pinMode(pirpin, INPUT);
  pinMode(pirled, OUTPUT);
  pinMode(pirrelay, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}
void loop(){
  pirv();
  output();
  blinkMyLeds();
  /*
  digitalWrite(led1, HIGH);
  delay(1000);
  digitalWrite(led1, LOW);
  delay(1000);
  digitalWrite(led2, HIGH);
  delay(1000);
  digitalWrite(led2, LOW);
  delay(1000);*/
}
void pirv(){
  current = millis();
  if(pirstate==LOW){
    if(current - previous >= on);
    {
      previous += on;
      if(digitalRead(pirpin)==HIGH){
        pirstate = HIGH;
      }
    }
  }
  else{
    if(current - previous >= duration){
      previous += duration;
      if(digitalRead(pirpin)==LOW){
        pirstate=LOW;
      }
    }
  }
}
void output(){
  digitalWrite(pirled, pirstate);
  digitalWrite(pirrelay, pirstate);
}
void blinkMyLeds()
{
  static unsigned long startTime;
  if (millis() - startTime < 1000UL)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led2,LOW);
  }
  else if (millis() - startTime < 2000UL)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
  }
  else
  {
    startTime = millis();
  }
}

Thanks guys. But my problem now is that during this program without other functions or delays just a program for pir
void loop(){
pir=digitalRead(pirpin);
if(pir==HIGH)
{delay(1000);
if(pir==HIGH){
for(int x=0; x<5;x++)
{
digitalWrite(pirled,HIGH);
digitalWrite(pirrelay,HIGH);
delay(1000);
if(digitalRead(pirpin)==HIGH)
{
x=0;
}
}
digitalWrite(pirled, LOW);
digitalWrite(pirrelay, LOW);
}
}
}
the operating function of my motion sensor is accurate, it detects continuously motion and outputs HIGH and when there is no motion, after 5 seconds, it signals LOW. But I want to incorporate my PIR function which is the pirv() from the previous program, to other functions, not just the LED blinking, but other functions, like stepper motor. My LED blinking are just my representation for my other functions. Now I learned functions working at the same time, thanks to you guys, I’ve changed the codes in my pirv() functions,
void pirv(){
current = millis();
if(pirstate==LOW){
if(current - previous >= on);{
previous += on;
if(digitalRead(pirpin)==HIGH){
pirstate = HIGH;
}
}
}
else{
if(current - previous >= duration){
previous += duration;
if(digitalRead(pirpin)==LOW){
pirstate=LOW;
}
}
}
}
void output(){
digitalWrite(pirled, pirstate);
digitalWrite(pirrelay, pirstate);
}
now it came out the detection of motion is not accurate, and it signals HIGH for just a few seconds and LOW’s for too long… I don’t know whats wrong… I’ve tried different approach with the millis() in the pirv() function, but still not accurate… I really appreciate your help guys… :slight_smile:

if(current - previous >= on);{

Semicolons can be very sneaky

Thanks for the advice. Now I deleted the semicolon. Still not getting my desired output

OK, before we go further, start here

Yes, code tags [ code ]…[ /code ] would be helpful.

Post your full code, in code tags.

Why are you using previous twice in both statements?

if(pirstate==LOW){
if(current - previous >= on){
previous += on;
if(digitalRead(pirpin)==HIGH){
pirstate = HIGH;
}
}
}
else{
if(current - previous >= duration){
previous += duration;
if(digitalRead(pirpin)==LOW){
pirstate=LOW;
}
}
}

They should be different variables, one for HIGH time and the other for LOW time.

Added:
Have you checked out the example sketch in the Arduino Playground? PIRsense

HazardsMind:
Yes, code tags [ code ]…[ /code ] would be helpful.

OOPS … they would, wouldn’t they :slight_smile:
(been there, done that)

…R

kenpitz:
Thanks for the advice. Now I deleted the semicolon. Still not getting my desired output

You could try looking for a state change on the pin, recording the time of that event and comparing it to the next state change event. For example, if your 5 seconds between trigger events is true, then output(). If you have another motion while the timer is running, extend the timer:

something like this untested code:

int pirPin=8, pirled=9, pirrelay=33, calibrationTime=15, pir;
int led1=18, led2=20;

byte lastPirState;
boolean isMotion = false;

unsigned long lastMotion;
unsigned long lastReadTime;

void setup()
{
  pinMode(pirPin, INPUT);
  pinMode(pirled, OUTPUT);
  pinMode(pirrelay, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}
void loop()
{
  byte pirState = digitalRead(pirPin);
  if (pirState = HIGH && lastPirState == LOW) // State shange on pirPin
  {
    unsigned long thisMotion = millis();
    if (thisMotion - lastMotion <= 5000UL)
    {
      isMotion = true;
    }
    lastMotion = thisMotion; // extends the output() timer if isMotion is already true
  }
  lastPirState = pirState;
  if (isMotion)
  {
    output();
  }
  blinkMyLeds();
}

void output()
{
  if (millis() - lastMotion < 5000UL)// 5 seconds of 'alarm state'
  {
    digitalWrite(pirled, HIGH);
    digitalWrite(pirrelay, HIGH);
  }
  else 
  {
    digitalWrite(pirled, LOW);
    digitalWrite(pirrelay, LOW);
    isMotion = false; // stop calling output()
  }
}
void blinkMyLeds()
{
  static unsigned long startTime;
  if (millis() - startTime < 1000UL)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led2,LOW);
  }
  else if (millis() - startTime < 2000UL)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
  }
  else
  {
    startTime = millis();
  }
}

[ code ]…[ /code ] tags… activated :blush: