Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

arduino - Fading Adafruit neopixels

I would like to create a motion-controlled night light for my corridor. For my project I have

  • Arduino Uno
  • PIR sensor
  • WS2812b RGBW light strip
  • 5V power bank to drive the LEDs

After tinkering with my light strip, I have managed to get the LEDs to turn on and fade to a low Red color followed by a delay and finally fade back to a point where they turn off. As I understand the Neopixel library, maximum light intensity has a value of 255. However, as we're talking about night light, I estimate that a value of less than 20 is more than sufficient to illuminate my corridor. (I should note that I see many suggestions placing a resistor in front of the LED strip and a capacitor on the power supply - will this affect intensity?) As a consequence, the light does not fade/turn off smoothly, but instead go through the lower intensities before turning off - which is not very pleasant to look at... My question is therefore if you know of any way to create a more smooth fade? Below is my code so far. Note that I have had to insert specific lines at the bottom to actually turn off the leds, as setting the intensity to "0" apparently doesn't seem to do the trick - am I missing something here?

Ideally I would like to be able to dictate how long it takes for the LEDs to fade in/out.

Thanks in advance

#include <Adafruit_NeoPixel.h>

#define LED_PIN     6

#define LED_COUNT  30 // How many NeoPixels are attached to the Arduino?
#define High_Intensity 20
#define Low_Intensity 1

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit... if you must, connect GND first.

void setup() {
  strip.begin();
  strip.show(); // initialize all pixels to "off"
}

void loop() {
  brighten();
  darken();
}

// 0 to 255
void brighten() {
  uint16_t i, j;

  for (j = Low_Intensity; j < High_Intensity; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, j, 0, 0);
    }
    strip.show();
    delay(50);
  }
  delay(500);
}

// 255 to 0
void darken() {
  Serial.begin(9600);
  uint16_t i, j;

  for (j = High_Intensity; j > 1; j--) { 
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, j, 0, 0);
    }
    strip.show();
    delay(100);
    Serial.println(j);
  }
  // Turn leds back off
  for(int i=0; i<60; i++)  {
  strip.setPixelColor(i, 0);
  strip.show();}
  delay(5000);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Regarding the off-topic part (I won't go into detail)

The capacitor between the power leads will protect the Neopixels controller from sudden voltage changes due to the fact that each pixel drives their leds with PWM.

The resistor terminates the communication lines which reduces reflections in the wires.

Both improve performance and reduce risk of damage to the pixels. Hence you should use them. Just make sure you use them on the correct pins. There's plenty of information online on how to properly control Neopixel strings.

(I should note that I see many suggestions placing a resistor in front of the LED strip and a capacitor on the power supply - will this affect intensity?)

This will not affect intensity! Intensity is only controlled by the pixels' pwm signal and the supplied current.

Programming-wise:

As I understand the Neopixel library, maximum light intensity has a value of 255.

Yes brightness is controlled by 3 values, red, green and blue each ranging from 0 (off) to 255 (max brightness). It's the duty cycle of the led's color channel. This gives you a brightness resolution of 256 values over the entire brightness range. (8 bit).

My question is therefore if you know of any way to create a more smooth fade?

This causes a problem. If you want to operate in a lower brightness range you only have a very limited number of steps to fade through.

So what if we reduce the current that supplies the leds? As control and led supply voltage are usually supplied through the same rail there is no way to dim the entire strip while keeping the 8-bit resolution.

To control the fading time alter the delay time between each value update. Keep in mind the limited dynamic and persistence of human vision. Any visible brightness change that happens < 30Hz will cause a noticable step.

Below is my code so far. Note that I have had to insert specific lines at the bottom to actually turn off the leds, as setting the intensity to "0" apparently doesn't seem to do the trick - am I missing something here?

for (j = High_Intensity; j > 1; j--) 

In the loop that darkens the strip you run the loop while j > 1. So the last brightness value you set is 2 which obviously isn't 0.

for (j = High_Intensity; j > -1; j--)

should do the trick.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...