Arduino Uno + I/O Shield + PIR Sensor + Relay != Trigger relay

Hi All,

Would appreciate your assistance with troubleshooting my attempt to use a PIR sensor to turn on/off the onboard Arduino Uno LED and turn on/off a relay (which controls a 120V light). The sensor works, the LED works, but the relay will only turn on and remain on ...

/****************************************************
Use a PIR sensor to turn on/off the onboard LED and turn on/off a relay (which controls a 120V light)

Materials Schedule

Arduino Uno - 1 each
https://store.arduino.cc/usa/arduino-uno-rev3
DF Robot Gravity I/O Shield - 1 each
https://www.dfrobot.com/product-1009.html
OSEPP Passive Infrared Sensor (PIR) Sensor HC-SR501 - 1 each
https://www.osepp.com/electronic-modules/sensor-modules/73-passive-infrared-sensor-pir-module
A-B Cable - 1 each

Wire Bundles - 3 female/female wires

Wire Bundle - 2 male/female wires

DLI IoT Relay - 1 each

Power Supply for Arduino 9V/1000mA - 1 each

120V Light - 1 each

Assembly

1.Connect A-B cable to arduino and laptop and upload sketch
2.Disconnect A-B cable
3.Connect aurduino and shield
4.Connect PIR sensor to arduino digital pin 3 with (3) female/female wires

(D) Digital Signal White
(+) Voltage VCC Red
(-) Ground GND Black

5.Connect IoT relay connector (+) (-) to arduino digital pin 13 with (2) male/female wires

(+) Voltage VCC Red
(-) Ground GND Black

*IoT Relay Frequently Asked Questions - FAQs
*About 0.2mA, the input is constant current
*12-120VAC or 3.3-48VDC will trigger the relay
*DC trigger input is polarity sensitive

6.Plug 9V power supply for arduino into relay outlet labeled "always on"
7.Plug 120V light into IoT relay outlet labled "normally off"
8.Plug IoT relay into mains outlet

Engineering

Originally created by rui santos

Modified by surfnm during 2019-01

****************************************************/

// Relay pin is controlled with digital pin 13. The active wire is connected to Normally Closed and common
// Volatile command https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/volatile/
int relay = 13;
volatile byte relayState = LOW;

// PIR Motion Sensor is connected to digital pin 3.
int PIRInterrupt = 3;

// Timer Variables
long lastDebounceTime = 0;
long debounceDelay = 10000;

// setup code here, runs once:
void setup() {

// Pin for relay module set as output
pinMode(relay, OUTPUT);
digitalWrite(relay, HIGH);

// PIR motion sensor set as an input
pinMode(PIRInterrupt, INPUT);

// Triggers detectMotion function on rising mode to turn the relay on, if the condition is met
attachInterrupt(digitalPinToInterrupt(PIRInterrupt), detectMotion, RISING);

// Onboard LED (Arduino Uno digital pin 13) setup
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

// Serial communication for debugging purposes
Serial.begin(9600);
}

// main code here, runs/loops repeatedly
void loop() {

// If 10 seconds have passed, the relay is turned off
if((millis() - lastDebounceTime) > debounceDelay && relayState == HIGH){
digitalWrite(relay, HIGH);
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
relayState = LOW;
Serial.println("Motion not detected: LED & Relay turned off");
}
delay(50);
}

// breakout of function used in the void loop
void detectMotion() {
Serial.println("Motion status");
if(relayState == LOW){
digitalWrite(relay, LOW);
}
relayState = HIGH;
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage HIGH
Serial.println("Motion detected: LED & Relay turned on");
lastDebounceTime = millis();
}

Please read the instructions for how to use this forum and fix your code posting.

The onboard LED is already attached to pin 13. You’re doubling up by attaching the relay to the same physical pin.

Move the relay to some other pin, change this line:

int relay = 13;

to the physical pin you used, recompile and test. There still may be issues with interrupts and other problems but the above is an obvious mistake.

BTW, you should not be using interrupts for a PIR. It’s totally unnecessary and problematic.

Appreciate your review and comment.

In a future post to this thread I will:

*repost my original code using requested board format
*post code & results of digital output test of i/o board (digital pins 13 & 12) - S. Monk 6-01
*post updated code using digital pin 12 & results
*post new code which does not use interrupts using digital pin 12 & results

One of my references includes Simon Monk’s ‘Programming Arduino’

Made a IoT Relay Test Sketch and a I/O Shield Test Sketch (D12 as an output pin for both sketches).

Wonder if the I/O board is functioning properly; should it continually provide 4.92V or should I buy another?

Test results:

Equipment. IoT Relay Test Sketch I/O Shield Test Sketch

Arduino+Multimeter 0V & 4.92V 0V and 4.92V
Arduino+I/O Shield+Multimeter 4.92V. 4.92V

Arduino+IoT Relay Light On/Off
Arduino+I/O Shield+IoT Relay Light On (Only)

IoT Relay Test Sketch

/****************************************************
Check IoT relay

  Materials Schedule
 
   Arduino Uno - 1 each
    https://store.arduino.cc/usa/arduino-uno-rev3
   Power Supply for Arduino 9V/1000mA - 1 each
    https://www.adafruit.com/product/63
   A-B Cable - 1 each
    https://www.staples.com/usb+ab+cable/directory_usb+ab+cable 
   Wire Bundle - 2 male/female wires
    https://www.adafruit.com/product/1954
   DLI IoT Relay - 1 each
    http://www.digital-loggers.com/iot2faqs.html
   120V Light - 1 each  

  Assembly
   1.Connect A-B cable to arduino and laptop and upload sketch
   2.Disconnect A-B cable   
   3.Plug 9V power supply for arduino into relay outlet labeled "always on" and plug into arduino 9V   
   4.Connect IoT relay connector (+) to arduino digital pin 12 (or your choice) with wire (male/female)
    
      (+) Voltage VCC Red

   5.Connect IoT relay connector (-) to a arduino GND pin with wire (male/female)

      (-) Ground  GND Black
      
   6.Plug light into IoT relay outlet labeled "normally off"
   7.Plug IoT relay into mains outlet

  Engineering

   Originally created by HowToMechatronics 
   Modified by surfnm during 2018-12
 ****************************************************/

// Global variables used throughout sketch
int relayIoT = 12; // digital pin (12 or your choice) is used to trigger relay

// Setup code, runs once:
void setup() {

  // Setup digital pin output to test IoT relay
  pinMode(relayIoT, OUTPUT);
  digitalWrite(relayIoT, HIGH);

  // Setup onboard LED (Arduino Uno digital pin 13)
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);    // Turns on onboard LED 
}


void loop() {
  digitalWrite(relayIoT, LOW); // Turns off digital pin (0V)
  digitalWrite(LED_BUILTIN, LOW);    // Turns off onboard LED
  delay(3000);
  digitalWrite(relayIoT, HIGH); // Turns on digital pin (5V)
  digitalWrite(LED_BUILTIN, HIGH);    // Turns on onboard LED
  delay(1000);
}

I/O Shield Test Sketch

/****************************************************
Check outputs on arduino i/o shield for digital pin 7 (or your choice)

Materials Schedule
 
  Arduino Uno - 1 each
   https://store.arduino.cc/usa/arduino-uno-rev3
  DF Robot Gravity I/O Shield - 1 each 
   https://www.dfrobot.com/product-1009.html
  A-B Cable - 1 each
   https://www.staples.com/usb+ab+cable/directory_usb+ab+cable  
  Wire Bundle - 2 male/female wires
   https://www.adafruit.com/product/1954 
  Multimeter - 1 each

Assembly
    
  1.Connect aurduino and shield
  2.Connect male/female wires to digital pin VCC (D12 or your choice) and ground (GND)
  3.Connect A-B cable to arduino and laptop and upload sketch
  4.Open serial monitor (upper right magnifying glass symbol)
  5.Enter 1 for 5V or 0 for 0V
  6.Connect multimeter probes (red to red & black to black), read output, and compare to serial monitor

     Red Wire - VCC (+) (D7 or your choice)
     Black Wire - GND (-)
  
Engineering

  Originally created Simon Monk 
   Programming Arduino: Getting Started with Sketches, 2nd Edition, sketch 6-01 
  Modified by surfnm
 ****************************************************/

// Global variables used throughout sketch

// Digital pin to be tested for ouput
const int outPin = 12; // digital pin to be tested (12 or your choice)

// Setup code, runs once:
void setup() {

  // Set digital pin to be tested as output
  pinMode(outPin, OUTPUT);

  // Set up serial monitor to query user for either 5V or 0V
  Serial.begin(9600); // Serial communication for debugging purposes
  Serial.println("Enter 1 (for 5V) or 0 (for 0V)"); // Start USB to UART proccess 

  // Setup onboard LED (Arduino Uno digital pin 13)
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);    // turn the onboard LED off 
  
}

// Main loop code, runs repeatedly 
void loop() {
  
if (Serial.available() > 0) { // Check that UART received data & buffered it
  char ch = Serial.read(); // Use local variable 'ch' to check user input
  if (ch == '1') {  
    digitalWrite(outPin, HIGH); // Turns on digital pin (5V)
    digitalWrite(LED_BUILTIN, HIGH);   // Turns on the onboard LED 
  }
  else if (ch == '0') { 
    digitalWrite(outPin, LOW); // Turns off digital pin (0V)
    digitalWrite(LED_BUILTIN, LOW);   // Turns off the onboard LED     
  }
 }
}

Original code updated from digital pin 13 to digital pin 12 and formatted using Arduino project guidance board style

/****************************************************
Use a PIR sensor to turn on/off the onboard LED and turn on/off a relay (which controls a 120V light)
 
  Materials Schedule
 
   Arduino Uno - 1 each
    https://store.arduino.cc/usa/arduino-uno-rev3
   DF Robot Gravity I/O Shield - 1 each 
    https://www.dfrobot.com/product-1009.html
   OSEPP Passive Infrared Sensor (PIR) HC-SR501 - 1 each
    https://www.osepp.com/electronic-modules/sensor-modules/73-passive-infrared-sensor-pir-module
   A-B Cable - 1 each
    https://www.staples.com/usb+ab+cable/directory_usb+ab+cable 
   Wire Bundles - 3 female/female wires 
    https://www.adafruit.com/product/266
   Wire Bundle - 2 male/female wires
    https://www.adafruit.com/product/1954
   DLI IoT Relay - 1 each
    https://dlidirect.com/products/iot-power-relay
   Power Supply for Arduino 9V/1000mA - 1 each
    https://www.adafruit.com/product/63
   120V Light - 1 each
     
  Assembly

   1.Connect A-B cable to arduino and laptop and upload sketch
   2.Disconnect A-B cable    
   3.Connect aurduino and shield
   4.Connect PIR sensor to arduino digital pin 3 with (3) female/female wires

      (D) Digital Signal White 
      (+) Voltage VCC Red
      (-) Ground  GND Black
   
   5.Connect IoT relay connector (+) (-) to arduino digital pin 12 with (2) male/female wires
   
      (+) Voltage VCC Red
      (-) Ground  GND Black

      *http://www.digital-loggers.com/iot2faqs.html
      *About 0.2mA, the input is constant current 
      *12-120VAC or 3.3-48VDC will trigger the relay
      *DC trigger input is polarity sensitive
      
   6.Plug 9V power supply for arduino into IoT relay outlet labeled "always on" 
   7.Plug 120V light into IoT relay outlet labeled "normally off"    
   8.Plug IoT relay into mains outlet

  Engineering

   Originally created by rui santos 
    https://randomnerdtutorials.com/guide-for-relay-module-with-arduino/ 
   Modified by surfnm during 2019-01
   
 ****************************************************/
// global variables


// Relay pin is controlled with digital pin 12. The active wire is connected to Normally Closed and common
// Volatile command https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/volatile/
int relay = 12;
volatile byte relayState = LOW;

// PIR Motion Sensor is connected to digital pin 3.
int PIRInterrupt = 3;

// Timer Variables
// Using millis() for timing. A beginners guide
// https://forum.arduino.cc/index.php?topic=503368.0
long lastDebounceTime = 0;  
long debounceDelay = 10000;


// setup code here, runs once:
void setup() {
  
  // Pin for IoT relay set as output
  pinMode(relay, OUTPUT);
  digitalWrite(relay, HIGH);
  
  // PIR motion sensor set as an input
  pinMode(PIRInterrupt, INPUT);
  
  // Triggers detectMotion function on rising mode to turn the relay on, if the condition is met
  attachInterrupt(digitalPinToInterrupt(PIRInterrupt), detectMotion, RISING);
  
  // Onboard LED (Arduino Uno digital pin 13) setup
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  
  // Serial communication for debugging purposes
  Serial.begin(9600);
}

// main code here, runs/loops repeatedly
void loop() {

  // If 10 seconds have passed, the relay is turned off
  if((millis() - lastDebounceTime) > debounceDelay && relayState == HIGH){
    digitalWrite(relay, HIGH);
    relayState = LOW;
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    Serial.println("Motion not detected: LED & Relay turned off");
  }
  delay(50);
}

// breakout of function used in the void loop
void detectMotion() {
  Serial.println("Motion status");
  if(relayState == LOW){
    digitalWrite(relay, LOW);
  }
  relayState = HIGH;  
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on by making the voltage HIGH
  Serial.println("Motion detected: LED & Relay turned on");
  lastDebounceTime = millis();
}

Mea culpa - operator wiring error

The I/O shield will provide 0V or 5V to the IoT relay from the Arduino with 2 wires when wired:

(D) Digital D12 Red Wire to IoT relay (+)
(+) Voltage VCC
(-) Ground GND Black Wire to IoT relay (-)

I had originally (and incorrectly) wired the I/O shield as:

(D) Digital D12
(+) Voltage VCC Red Wire to IoT relay (+)
(-) Ground GND Black Wire to IoT relay (-)