Qwiic PIR Hookup Guide
Arduino Examples
The SparkFun Qwiic PIR Arduino Library includes five examples to help users get started with the board and library. In this section we'll go over a few of the examples and highlight how they work.
Example 1 - Print Raw PIR Status
The first example demonstrates how to set up the Qwiic PIR on your I2C bus and then retrieve raw data readings from the Qwiic PIR using the rawPIRReading();
function. Open the first example by navigating to File > Examples > SparkFun Qwiic PIR Arduino Library > Example1_PrintRawPIRStatus. Next, open the Tools menu and select your board (in our case, Arduino Uno) and the correct Port your board enumerated on. Upload the code and open your serial monitor with the baud set to 115200.
The example first sets up the Qwiic PIR object and debounce time (in milliseconds):
language:c
QwiicPIR pir;
#define DEBOUNCE_TIME 750
Next it initializes the sensor and then waits 30 seconds for the PIR to warm up and stabilize.
language:c
if (pir.begin() == false) {
Serial.println("Device did not acknowledge! Freezing.");
while (1);
}
Serial.println("PIR acknowledged. Waiting 30 Seconds while PIR warms up");
for (uint8_t seconds = 0; seconds < 30; seconds++)
{
Serial.println(seconds);
delay(1000);
}
The code will freeze if the Qwiic PIR does not acknowledge on the I2C bus at the default address. A bad connection or a different I2C address are the most common causes of this failure.
Once the PIR warms up the main loop checks whether rawPIRReading();
returns TRUE
or FALSE
and waits to update again for the value set for DEBOUNCE_TIME
. The code prints out objects detected or removed via serial. Take note when using the rawPIRReading();
any debouncing of the signal must be done manually.
Example 2 - Print PIR Status
The second example is very similar to the first but uses the objectDetected();
and objectRemoved();
functions instead of rawPIRReading();
. The primary difference between these functions is where debouncing the PIR signal happens. Instead of manually debouncing the PIR signal each time it occurs, the objectDetected();
and objectRemoved();
functions refer to the value stored for setDebounceTime(uint16_t time);
and will automatically debounce the signal for that time. The default value for setDebounceTime();
is 750ms.
Open the example, upload it and open a serial terminal set to 115200 baud. After initializing the sensor and waiting for 30 seconds for the PIR to warm up, the code will start polling the PIR for events and prints what they are over serial:
language:c
if (pir.available()) {
if (pir.objectDetected()) {
Serial.println("Object Detected");
}
if (pir.objectRemoved()) {
Serial.println("Object Removed");
}
pir.clearEventBits();
}
Example 3 - Queue Usage
The third example included with the library shows how to read and manipulate the Object Detected and Object Removed queues. After uploading the example, open a serial terminal with the baud set again to 115200. After initializing the Qwiic PIR, the main loop checks if either the Detected or Removed queues have values stored for either time (in seconds) since first detect/remove or time since last detect/remove and prints them over serial. If no values are present in either queue, the code prints out which queue is empty:
language:c
if(pir.isDetectedQueueEmpty() == false) {
Serial.print(pir.timeSinceLastDetect()/1000.0);
Serial.print("s since PIR detect ");
Serial.print(pir.timeSinceFirstDetect()/1000.0);
Serial.print("s since PIR detect ");
}
if(pir.isDetectedQueueEmpty() == true) {
Serial.print("PIR Detected Queue is empty! ");
}
if(pir.isRemovedQueueEmpty() == false) {
Serial.print(pir.timeSinceLastRemove()/1000.0);
Serial.print("s since PIR remove ");
Serial.print(pir.timeSinceFirstRemove()/1000.0);
Serial.print("s since PIR remove ");
}
if(pir.isRemovedQueueEmpty() == true) {
Serial.print(" PIR Removed Queue is empty!");
}
Along with printing values from each queue, this example also shows how to manipulate and pop values from any queue:
language:c
if(Serial.available()) {
uint8_t data = Serial.read();
if(data == 'd' || data == 'D') {
pir.popDetectedQueue();
Serial.println("Popped DetectedQueue!");
}
if(data == 'r' || data == 'R') {
pir.popRemovedQueue();
Serial.println("Popped RemovedQueue!");
}
}
delay(20);
With a serial terminal open, send the letter "D" (capitalized or not) to pop a value off the Detected Queue. Similarly, send the letter "R" to pop a value off the Removed Queue.
Example 4 - External Interrupt
Example 4 - ExtInterrupt demonstrates how to use the Interrupt pin on the Qwiic PIR.
Along with setting up the Qwiic PIR in the global class, the code defines the interrupt pin and creates an interrupt flag:
language:c
int interruptPin = 2;
bool interruptEntered = false;
Adjust the value for your interrupt pin as needed. This example assumes a SparkFun RedBoard/Arduino Uno is used and sets D2 as the interrupt pin. In the setup, the code initializes the Interrupt pin as an input and attaches it as a falling-edge interrupt to a custom function called pirHandler
:
language:c
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), pirHandler, FALLING);
After initializing the Qwiic PIR on the bus and waiting for 30 seconds for the PIR to warm up, the code calls the enableInterrupt();
and clearEventBits();
functions to tell the Qwiic PIR to trigger the pin on object events and clears any event bits to toggle the Interrupt pin HIGH
:
pir.enableInterrupt();
pir.clearEventBits();
The main loop checks for motion events and if any are detected it will fire the interrupt pin:
language:c
void loop() {
if (interruptEntered)
{
if (pir.objectDetected()) {
Serial.println("Object Detected");
}
pir.clearEventBits();
interruptEntered = false;
delay(10);
}
}
void pirHandler()
{
interruptEntered = true;
}
From here, you can modify this example or insert it into more complex code to trigger whatever interrupt event you would like using the Qwiic PIR.