Go Down

Topic: PIR Motion Sensor, Adafruit NeoPixel Digital RGB LED Strip (Read 2785 times) previous topic - next topic

JamesHayek

Hello,

   I took existing code that runs on the LED strip and wanted to tie it into the Parallax PIR motion sensor. The example code for the sensor sends a digitalWrite() function to the Arduino.

I tried to enter my function that drives the LED strip as opposed to a simple "on and off" to a single LED.

The Motion sensor example code is as follows:

Code: [Select]
/* 
    Motion sensor for Arduino, example code
    Tutorial:  http://www.hacktronics.com/Tutorials/arduino-motion-sensor.html
    Copyright: Mark McComb, hacktronics LLC
    License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
*/

const byte ledPin =  6;    // LED pin
const byte motionPin = 2;   // motion detector input pin
byte senseMotion = 0;       // variable to hold current state of motion detector

void setup() {
  // set the digital pin directions
  pinMode(ledPin, OUTPUT);     
  pinMode(motionPin, INPUT);
}

void loop()
{
    // Now watch for burglers
    senseMotion = digitalRead(motionPin);
      if (senseMotion == HIGH) {    // burgler found!
      digitalWrite(ledPin, HIGH);
    } else {                      // no burgler, yet...
      digitalWrite(ledPin, LOW);
    }
}


I modified it to this:

Code: [Select]
#include <Adafruit_NeoPixel.h>

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(120, 6, NEO_GRB + NEO_KHZ800);

const byte motionPin = 2;   // motion detector input pin
byte senseMotion = 0;       // variable to hold current state of motion detector


void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

pinMode(motionPin, INPUT);
   
   
}

void loop() {



senseMotion = digitalRead(motionPin);

      if (senseMotion == HIGH) {    // burgler found!
  colorChase(strip.Color(127,   0, 127), 10); // Violet
  strip.show(); // Initialize all pixels to 'off'
  delay(1000);

    } else {                      // no burgler, yet...
  scanner(127,0,127, 15); // Violet
  strip.show(); // Initialize all pixels to 'off'

    }

 
  //Monocramatic Effect Sequence
  //colorChase(strip.Color(127,   0, 127), 10); // Violet
  //colorWipe(strip.Color(127, 0, 127), 10); // Violet
  //myCrap(strip.Color(127,0,127),10); //Violet
  //scanner(127,0,127, 15); // Violet

  //myCrap2(strip.Color(0,0,0),10); // Off
  //wave(strip.Color(127,0,127), 2, 40); // Violet
  //rainbow(20);
  //rainbowCycle(20);
   
 
 
}




// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}


void myCrap(uint32_t c, uint8_t wait) {
  for(uint16_t k=0; k<strip.numPixels(); k++) {
   
      strip.setPixelColor(2*k, c);
      strip.show();
      delay(wait);   
   
  }
 
 
}



void myCrap2(uint32_t c, uint8_t wait) {
  for(uint16_t k=0; k<strip.numPixels(); k++) {
   
      strip.setPixelColor((2*k+1), c);
      strip.show();
      delay(wait);   
   
  }
 
 
}



void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}


// Chase one dot down the full strip.
   void colorChase(uint32_t c, uint8_t wait) {
   int i;

  // Start by turning all pixels off:
    for(i=0; i<strip.numPixels(); i++) strip.setPixelColor(i, 0);

  // Then display one pixel at a time:
    for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c); // Set new pixel 'on'
    strip.show();              // Refresh LED states
    strip.setPixelColor(i, 0); // Erase pixel, but don't refresh!
    delay(wait);
  }

  strip.show(); // Refresh to turn off last pixel
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


// "Larson scanner" = Cylon/KITT bouncing light effect
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
  int i, j, pos, dir;

  pos = 0;
  dir = 1;

  for(i=0; i<((strip.numPixels()-1) * 8); i++) {
    // Draw 5 pixels centered on pos.  setPixelColor() will clip
    // any pixels off the ends of the strip, no worries there.
    // we'll make the colors dimmer at the edges for a nice pulse
    // look
    strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4));
    strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos, strip.Color(r, g, b));
    strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4));

    strip.show();
    delay(wait);
    // If we wanted to be sneaky we could erase just the tail end
    // pixel, but it's much easier just to erase the whole thing
    // and draw a new one next time.
    for(j=-2; j<= 2; j++)
        strip.setPixelColor(pos+j, strip.Color(0,0,0));
    // Bounce off ends of strip
    pos += dir;
    if(pos < 0) {
      pos = 1;
      dir = -dir;
    } else if(pos >= strip.numPixels()) {
      pos = strip.numPixels() - 2;
      dir = -dir;
    }
  }
}




My "else" statement is running and the detector is not sensing any movement. Any clues as to why?


Thanks in advance



Fexduino

Hi dude,


I might be able to solve this one. Your schematic is very basic, so I am going to assume that is all good. I also have hookedd up my LED's to a PIR sensor. I have both the Parallax and Sparkfun type and they both work in a different way. Just to make sure, the PIR is working in an example sketch right?

Anyway, my sensors give me random data when I power the LED's through my Arduino. I noticed that it did do detections, but whenever I started doing patterns the PIR would simply give random. Hooking up the LED strip to an external power supply totally solved the problem. The reason for this I think is that the ws2811 leds draw too much current from the arduino causing the pins to drop theirs.

Be sure to feed the GROUND of the LEDs back to the Arduino! (very important)


fungus


Hooking up the LED strip to an external power supply totally solved the problem. The reason for this I think is that the ws2811 leds draw too much current from the arduino causing the pins to drop theirs.


120 RGB LEDs @ 20mA = 7.2 Amps if you switch them all on at the same time.

(fifteen times more than a USB port can provide...!)

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)


fungus

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

JamesHayek

Right, but why 3? We must consider .02A for each channel, R,G, and B?

fungus

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

ImXron

Hey James,

quick question, was looking for that "scanner effect" and saw yours. When I tried to compile my code it says that scanner function has too few arguments?

All the other functions im using work fine. Let me know if you have any suggestions, thanks!

JamesHayek



The scanner function is as follows:

Code: [Select]
// "Larson scanner" = Cylon/KITT bouncing light effect
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
  int i, j, pos, dir;

  pos = 0;
  dir = 1;

  for(i=0; i<((strip.numPixels()-1) * 4); i++) {
    // Draw 5 pixels centered on pos.  setPixelColor() will clip
    // any pixels off the ends of the strip, no worries there.
    // we'll make the colors dimmer at the edges for a nice pulse
    // look
    strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4));
    strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos, strip.Color(r, g, b));
    strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2));
    strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4));

    strip.show();
    delay(wait);
    // If we wanted to be sneaky we could erase just the tail end
    // pixel, but it's much easier just to erase the whole thing
    // and draw a new one next time.
    for(j=-2; j<= 2; j++)
      strip.setPixelColor(pos+j, strip.Color(0,0,0));
    // Bounce off ends of strip
    pos += dir;
    if(pos < 0) {
      pos = 1;
      dir = -dir;
    }
    else if(pos >= strip.numPixels()) {
      pos = strip.numPixels() - 2;
      dir = -dir;
    }
  }


Notice there are four arguments we must consider when the original designer made the function;

Code: [Select]
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait)


Your call to the function must have four arguments. One for each channel, R, G and B and then a time value.

Your call should look something like this:

Code: [Select]

          scanner(127, 0,127, 10); // Violet  running at a speed of 10


ImXron

Thanks James, wasn't calling the function correctly!

Go Up