2

I am trying to use this example(it works on Arduino Mega): millis() - lowIn comes greater than 5000when motion ends.

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 3; //the digital pin connected to the PIR sensor's output
int ledPin = 13;

/////////////////////////////
//SETUP
void setup() {
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, 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) {
    digitalWrite(ledPin, HIGH);
    //the led visualizes the sensor's 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(ledPin, 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
    Serial.print(millis() - lowIn);
    Serial.print("    ");
    Serial.print(lockLow);
    Serial.print("    ");
    Serial.println(pause);
    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);
    }
  }
}

But it doesn't work on a Yún shield mounted on an Arduino Leonardo. The difference of millis() - lowIn always comes out to be lower than pause.

1

The Arduino Leonardo uses the ATmega32U4 microcontroller which uses lower logic levels for the digital inputs. Perhaps that is not compatible with the PIR sensor. You can simulate the PIR sensor with a piece of wire and connect it to 5V or GND.

For the Leonardo, sometimes "SerialUSB" is used instead of "Serial". But if see a message on the serial monitor then "Serial" is okay.

If you can't make it work, then try to reduce the number of variables. In this case, remove the Yun shield and try it with the Leonardo board.

The Arduino Mega 2560 and Arduino Leonardo have both a 8-bit microcontroller and 'millis' works on both in exactly the same way. Therefor 'millis' itself or the variables can't be the problem.

2
  • what do you mean by "You can simulate the PIR sensor with a piece of wire and connect it to 5V or GND." ? – Ciasto piekarz Jun 14 '17 at 10:42
  • Instead of the PIR sensor, connect a piece of wire to pin 3 and connect that to either GND or 5V. That's all. It is just a test, perhaps there is trouble with the voltage level of the PIR sensor (but I don't know). – Jot Jun 15 '17 at 5:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.