Software

Adafruit Feather Bluefruit nRF52

Be sure to follow the guide below to install the board and libraries. When you've installed the Bluefruit Arduino profiles and libraries, come back here and continue the tutorial.

Bluetooth App + NeoPixel Color Picker

The Adafruit Feather bluefruit has an on-board Bluetooth Low-Energy module that allows you to connect via the Adafruit Bluefruit Connect iOS/Android App. Using the mobile app, you can choose different colors and brightness to change the NeoPixels on the fly. To get this sketch up and going, you can follow the Bluefruit nRF52 learning guide. There, it will walk you through the installation process.

NeoPixel Demo

For something really quick, I used this sketch to showcase the NeoPixels. This does not feature any special bluetooth control. This sketch is a compilation of animations. It cycles through different sequences that display different colors. It's great for just getting a lot of effects like rainbows, theater chasers and color wipes. This will also work with the Adafruit Feather proto basic if you don't want the extra cost a bluetooth module.

Uploading Sketch to Adafruit Feather Bluefruit

To load the sketch make sure the libraries above are installed, and the Arduino is connected to the computer through a USB cable.  Under the Tools -> Board menu make sure the Adafruit Bluefruit Feather nrf52 is selected, and under the Tools -> Port menu the serial port "/dev/cu.SLAB_USBtoUART" is selected.  

Then press the upload button or click the Sketch -> Upload item to send the code to the Arduino.  Woo-hoo the sketch should be running.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 30

Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);

//Color
    uint8_t red = 255;
    uint8_t green = 255;
    uint8_t blue = 255;
    uint8_t animationState = 1;

    int pos = 0, dir = 1; // Position, direction of "eye" for larson scanner animation

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  strip.setBrightness(40);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  
  larsonScanner(strip.Color(255,0,0), 60);
  larsonScanner(strip.Color(255,0,20), 60);
  larsonScanner(strip.Color(255,0,40), 60);
  larsonScanner(strip.Color(255,0,60), 60);
  larsonScanner(strip.Color(255,0,70), 60);
  larsonScanner(strip.Color(255,0,80), 60);
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  colorWipe(strip.Color(255, 100, 0), 50); // Organge
  colorWipe(strip.Color(100, 0, 255), 50); //purple
  colorWipe(strip.Color(0, 100, 255), 50); // cyan
  colorWipe(strip.Color(0, 0, 0), 50);
  colorWipe(strip.Color(255, 0, 0), 50);
  rainbow(20);
  rainbowCycle(10);
  theaterChaseRainbow(60);
}

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

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<4; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 2; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+6) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+6) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 6; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+6) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+2) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

void larsonScanner(uint32_t c, uint8_t wait){
   int j;
   
 for(uint16_t i=0; i<strip.numPixels()+5; i++) {
  // Draw 5 pixels centered on pos.  setPixelColor() will clip any
  // pixels off the ends of the strip, we don't need to watch for that.
  strip.setPixelColor(pos - 2, 0x100000); // Dark red
  strip.setPixelColor(pos - 1, 0x800000); // Medium red
  strip.setPixelColor(pos , 0xFF3000); // Center pixel is brightest
  strip.setPixelColor(pos + 1, 0x800000); // Medium red
  strip.setPixelColor(pos + 2, 0x100000); // Dark red
  
  strip.show();
  delay(wait);
 
  // Rather than being sneaky and erasing just the tail pixel,
  // it's easier to erase it all and draw a new one next time.
  for(j=-2; j<= 2; j++) strip.setPixelColor(pos+j, 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;
  } 
 } 
 //colorWipe(pixel.Color(0, 0, 0), 20);
}

// 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);
}
Last updated on May 17, 2017 Published on May 17, 2017