First Neopixel Project

Hi all,

Sorry if this turns out to be a really stupid questions, but I’m coming from the world of Raspberry Pi to the land of Arduino.

I’m using an Arduino Uno R3 and have a string of 300 neopixels, I’m planning to use them in my office to light the underside of some cabinets.

I have wired them up, and been following the guide on this page but I’m having two issues.

Note, the diagram on that page is actually wrong, some of the pins are the wrong number, anyway. Firstly, power…

I have a 5V 10Amp laptop style power brick, there’s plenty enough power in this thing, but after about 1 - 1.5 metres, the led’s start drifting into the yellow spectrum of colour when they’re actually set at full white, at the end of the strip, they’re basically orange, how do I combat this? I’m guessing by reading this page and adding in fly leads about every metre distributing power directly to that spot? If so, what’s the best way to accomplish this without damaging the strips?

Second, and this is a code related question, below is my entire code, which for the most part seems to work.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif
//VARS
#define PIN 5

// 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)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(300, PIN, NEO_GRB + NEO_KHZ800);/////////////////////////////


//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 5;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000;  

boolean lockLow = true;
boolean takeLowTime;  

int pirPin = 6;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;
// 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'

    Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
}

void loop() {

     if(digitalRead(pirPin) == HIGH){
       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
        Serial.println("Rainbow Cycle");
        rainbowCycle(1);
        Serial.println(" Turning Lights On");
        colorWipe(strip.Color(255, 255, 255), 1); // White
        delay(5000);
       if(lockLow){ 
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---"); 
         delay(50);
         }         
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){ 
       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){
        //colorWipe(strip.Color(0, 0, 0), 20); // OFF
        Serial.println("Fade To Dim Red");
        for(int i=255; i>30; i--){
        colorWipe(strip.Color(i, i, i), 1); 
        }
        colorWipe(strip.Color(50, 0, 0), 1);
        Serial.println("Fade Red Completed");  
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           delay(50);
           }
       }
       
  }

// 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 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);
  }
}

// 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) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

but id like to do 2 things which right now I just cannot figure out. Firstly, il explain my loop.

Once motion is detected from the PIR sensor, there’s a quick rainbow show thing, then the light is set to all white for 5 seconds and a motion reading is taken again, if no more motion then it will fade to a dim white and then flick to a dim red. If motion was detected it will show the rainbows again and then show the white light again.

What I want it to do is this… Detect Motion > Show rainbows > Show white for 5 seconds and take a motion reading > If no motion detected Fade down to a dim red > once motion has been detected, loop back to the start with the rainbow light show

The difficulty here is that once the light has gone white, if the sensor retriggers (motion is still present after the 5 second timeout) then it shows the rainbow pattern again, this is what I want to stop. The rainbows should only be displayed once the system has not detected motion for a while and has gone into its standby mode (dim red), if it retriggers when the white light is already on, it should simply keep the white lights on (as they already would be) wait for the 5 second timer to elapse and check again, not show the rainbows again.

Also, the fade to a dim white takes about 5 minutes, and I cant seem to get it to fade from full white to a dim red directly.

Id appreciate any replies at all, I’m finding a big jump between RPI and Arduino, but don’t think I’m doing too badly!

Thanks guys.

I have a 5V 10Amp laptop style power brick, there's plenty enough power in this thing,

No you haven't, that number of LEDs will draw 18A.

Note, the diagram on that page is actually wrong,

Yes their is no seriese resistor on the data lines and their is no large capacitor on the supply.

this is a code related question,

Basically the code is not written as a state machine and so has to wait until sequences have finished before it can look at anything. Basically this is caused by using delay inside a for loop.
You need to rewrite the code as a state machine.
See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once

Hi Mike, thanks for the reply.

No worries, I realised last night, I had probably done my calculations wrong, il organise a larger amperage power supply.

Yes, with regards to the series resistor and large capacitor, I read these were needed on the Adafruit site and I am using these.

Il take a look at your 2 links and see if I can make sense of them, I am learning the code but this is my first real effort with anything Arduino related.

but I'm coming from the world of Raspberry Pi to the land of Arduino.

Did you program on the Pi? If so what language did you use? The same basic techniques apply to the Pi as well as the Arduino.

Yep, I did program on the RPI platform, on that I used python (which is a nightmare!). Wrote loads of things for that but in the grand scheme of thing they’re probably all reasonably basic.

Python can be very similar to C with just minor changes to syntax. So you can carry that over to the Arduino. I often write state machine code in my Raspberry Pi projects that I publish in the MagPi.

Be interested in the end result of this CS2000

Tthanks for the replies so far, I have spent the last few day building a 'proper' PCB on some perf board rather than the rats nest of wires I had, plus I have added in the required capacitor and resistor to the PCB as recommended by adafruit.

I'm still working on the code, but I'm having the learn everting new, so as usual any further help is appreciated. If/when I figure it out, il post the code in here, who knows how useful it will be, but still!