hello all, i'm doing a univercity project where we want to light small mushroom like light on the ground using a neopixle led strip and a PIR movement sensor to turn it on and off. The led strip does not turn off after being turned on and I cant find the error, hopefully you guys can.
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#include <SoftwareSerial.h>
int pirPin = 2; // PIR Out pin
int pirStat = 0; // PIR status
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 6 // Popular NeoPixel ring size
// When setting up 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.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pinMode(pirPin, INPUT);
Serial.begin(9600);
}
void loop() {
pirStat = digitalRead(pirPin);
if (pirStat == HIGH){
pixels.clear(); // Set all pixel colors to 'off'
Serial.println("1");
// The first NeoPixel in a strand is #0, second is 1, all the way up
// to the count of pixels minus one.
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels.setPixelColor(i, pixels.Color(252, 202, 3));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(DELAYVAL); // Pause before next pass through loop
if (pirStat == LOW) //If no movement detected....
{
Serial.println("0");
pixels.setPixelColor(i, pixels.Color(0, 0, 0));} //turn all pixels black 'off'
}
}
}
You are not calling pixels.show() when turning off the pixels
However, there are other problems. Whatever the state of the PIR you turn on the LEDs only to turn them off again afterwards. Is that what you intended or was your code intended to be more like
if the PIR has detected movement
{
turn on the LEDs
}
else
{
turn off the LEDs
but I dont seem to find a way to tell the damn thing to turn off after the PIR does not detect movement. It just stays on (it actually blinks because of the pixels.clear(); command at the start of the loop) but it does not seem to turn off.
Hi,
I recommend that you post a schematic of your project.
But for now do this, test this modification in your code:
// https://forum.arduino.cc/t/neopixel-does-not-turn-off/966701
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#include <SoftwareSerial.h>
int pirPin = 2; // PIR Out pin
int pirStat = 0; // PIR status
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 6 // Popular NeoPixel ring size
// When setting up 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.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
//-----------------------------------------------------------------------
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pinMode(pirPin, INPUT);
Serial.begin(9600);
}
//-----------------------------------------------------------------------
void loop() {
pirStat = digitalRead(pirPin);
if (pirStat == HIGH)
{
pixels.clear(); // Set all pixel colors to 'off'
Serial.println("1");
// The first NeoPixel in a strand is #0, second is 1, all the way up
// to the count of pixels minus one.
for (int i = 0; i < NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels.setPixelColor(i, pixels.Color(252, 202, 3));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(DELAYVAL); // Pause before next pass through loop
// removed by ruilViana
/* if (pirStat == LOW) //If no movement detected....
{
Serial.println("0");
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
} //turn all pixels black 'off' */
}
}
else
pixels.clear(); // Set all pixel colors to 'off'
}
@UKHeliBob gave you a clue. Isn´t your code missing a pixel.show()? Here:
if (pirStat == LOW) //If no movement detected....
{
Serial.println("0");
pixels.setPixelColor(i, pixels.Color(0, 0, 0));} //turn all pixels black 'off'
pixel.show()
}
loop
turn on or off the next pixel according to the pir reading
show the strip…
delay a bit. depends on how long the strip is 200 ms?
cackulate next, index++, reset to zero at number of pixels on strip
Start by removing the test for pirStat being LOW because that must be it's state if it is not HIGH. Instead change the test into an else
Instead of using setPixelColor() to set each pixel individually using a for loop consider using a single call to the fill() function to set the colour of all of the pixels at once
If you don't want to do that then at least take the call to show() out of the for loops as it only needs to be done once, not for each LED