Hi, I need some help with my code a PIR sensor and Neopixel LED Strip, Please.

Hi,

I really need some help for my project please. What I'm trying to do is using a PIR sensor get a LED strip to fade on with movement and then if there is no movement after 5 mins fade off.

Thank you so much I really appreciate any help!!

here is my code

#include <Adafruit_NeoPixel.h>

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16
#define LED_PIN 8
#define MAXLEVEL 100 // do not exceed 150!!!

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
// See the explanations from the Adafruit library
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LED_PIN, NEO_GRBW + NEO_KHZ800);

// Some pin defs for the motion click
#define MOTION_PIN 2 // interrupt pin for motion sensor

int MotionDetected;
//int val = 0;
long firstTimeNoMovement;
long timeSinceNoMovement;
boolean movement;
boolean sensorValue;
//int pirState = on;

void setup() {
pixels.begin(); // This initializes the NeoPixel library
//attachInterrupt(0, MotionIrq, RISING); // ATMEGA2560 - Pin D2 is INT0
//MotionDetected = 0; // initial setting
pinMode(MOTION_PIN, INPUT);
pinMode(LED_PIN, OUTPUT); // set enable pin as output
Serial.begin(9600);
// turn off all leds
for (int i = 0; i < NUMPIXELS; i++) {
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.

}
}

void loop() {
// *** Read sensor value: on/off, or true/false, 0/1, etc
sensorValue = digitalRead(MOTION_PIN);
if (movement == true) {
for (int j = 1; j < MAXLEVEL; j++) {
for (int i = 0; i < NUMPIXELS; i++) {
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0, 0, j)); // Bright blue color.
pixels.show(); // This sends the updated pixel color to
movement = true;
}
}
} else if (movement == true) {
firstTimeNoMovement = millis();
movement = false;
// Check time passed since no movement detected
long currentTime = millis();
long timeSinceNoMovement = currentTime - firstTimeNoMovement;
}
if (timeSinceNoMovement > 60000) {
for (int j = MAXLEVEL; j > 0; j--) {
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(0, 0, j - 1));
pixels.show();
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Black/ off
}
}
}
}

int getTimeInMillis(int sec) {
return sec * 1000;
}

Welcome to the forums. Please read the sticky post at the top about how to post your code (using code tags) so it makes it easy for people to help you.

A couple of things....

  • you call pixels.show() every time through the for() loop. Don't do that. Use the for() loop to set all the colors and then when you are done, call it once to display it.

  • You have

if(movement == true)
{ ... }
else if (movement == true)
{ ... }

You don't need to test the variable twice.

-You also never use sensorValue? Shouldn't you be testing that variable and then setting movement true or false?

-you declare timeSinceNoMovement inside your else clause so it goes out of scope as soon as that exists, yet you use it later (the global one, not the local one) These are two different variables.

I'd implement this as finite state machine.

Four states.
IDLE: wait for movement. When detected, go to FADEIN.
FADEIN: movement detected, fade LEDs in. WHen complete, go to ON.
ON: when FADEIN completes; full brightness. 5 mins after last movement detected go to FADEOUT.
FADEOUT: fade LEDs out. When complete, go to IDLE.

Separately: continue to check whether your PIR detected movement, to keep track when it last detected movement.

Something like this:

enum LedStates {
  IDLE,
  FADEIN,
  ON,
  FADEOUT
};
LedStates ledState = IDLE;

void loop() {
if (digitalRead(MOTION_PIN)) {
  lastMovementTime = millis();
  switch (LED_STATE) {
    case IDLE:
    case FADEOUT:
      LED_STATE = FADEIN;
      break;
  }
}

switch (LED_STATE) {
  case FADEIN:
    // fade LED in.
    break;

  case ON:
    // Check for motion timeout.
    break;

  case FADEOUT:
    // fade LED out.
    break;
}
}