Overview

You'll be a rainbow in any storm with the FLORAbrella. With its NeoPixel LED strips and color sensor, you'll be able to match your clothing, or display rainbow and rain patterns. Get ready to have an entourage at the next parade!

For this project, you'll need to create the circuit, mount it in the dome of the umbrella, and then finish it off by creating clear vinyl hammocks for the battery, FLORA and color sensor. This is an intermediate-level project that requires some precise soldering on the LED strips, so just stay away from caffeine and keep your cat away. Also, make sure you read and practice the following guides:
Okay, let's get the supplies!

Tools and Supplies


For this project you will need:

Circuit Diagram

NeoPixels and color sensor face outside of umbrella, FLORA main board faces interior of umbrella. Other connections as follows:

FLORA GND-> NeoPixels GND (all)
FLORA VBATT-> NeoPixels 5V (all)
FLORA D6-> NeoPixels DIN (data in)
FLORA GND -> color sensor GND
FLORA SCL -> color sensor SCL
FLORA SDA -> color sensor SDA
FLORA 3V -> color sensor 3V
FLORA D10 -> pushbutton to GND

Test the NeoPixel Strip

Let's start by lighting up 5 meters of NeoPixel strip, just to be sure it's working properly (and it's just an awesome experience). To do this, you will need your alligator clips, the third hand, your NeoPixel strip, FLORA and battery.

This is just a friendly reminder that you need to review the FLORA and NeoPixel guides to perform this test. You don't want to damage anything, right?

Configure the FLORA

Connect the FLORA to your computer using the USB cable. Follow the instructions on the Flora tutorial and don't forget to install the NeoPixel library. Then, load the following modified version of the NeoPixel example "strandtest". Once it is loaded, you can turn off the power and unplug the USB cable.
#include <Adafruit_NeoPixel.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = 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(160, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.setBrightness(30); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  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 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) {
  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);
  }
}

Test the NeoPixel Strip

Unwind your NeoPixel strip on a table or other flat surface. You may want to tape it here and there with masking tape just to keep it from moving. Since you have a 5 meter quantity of strip, you will see test leads on one end. Hook up the LED strip to the FLORA micro-controller with alligator clips in this fashion (the third hand may be helpful here to keep the wires separated).

  • Black alligator clip - ground (GND) pin on strip --> ground (GND) pin on FLORA
  • Red alligator clip - 5V pin on strip --> VBATT pin on FLORA
  • Blue alligator clip - DIN pin on strip --> D6 on FLORA

Make sure you double check the sketch to be sure the quantity of NeoPixels (160) and the pin number for the FLORA are set correctly (usually 6 or 12). Set the brightness low to start out (30). Also, check that the arrows on the NeoPixel strip are pointing away from the FLORA. Finally, take one last look at the alligator clips to be sure they are not touching each other. Now, plug the battery into the FLORA and switch on the power. You should see a fun LED show with different patterns. If not, don't worry, just double check your connections and double check the sketch you loaded into the FLORA. Got it? If so, it's time to move on to the circuit.

Solder FLORA circuit

Arrange FLORA and the color sensor in your third hand tool as shown, facing opposite each other but still with 3v, SCL, SDA, and GND pads aligned.

Solder four short wires to FLORA and clip off any excess.
Trim and strip these wires to line up to the color sensor, then solder all four and clip off any excess wire.
Trim two diagonal pins from a tactile switch, and then poke the remaining two legs through D10 and GND on FLORA.

Solder in place.
The resulting circuit will live in the edge of the umbrella, facing the color sensor to the outside and the FLORA's power switch and the mode-selecting button you soldered facing in towards you as you use it.

Now that your color sensor is attached, you can test it out by hooking up your NeoPixels and running the sample code included with the color sensor library, the Chameleon Scarf code, or the code included later in this guide.

Prepare NeoPixel Strip

Unwind a section of NeoPixel strip from your spool and clip it into one rib of your umbrella. Decide how long you want each strip, and clip with diagonal cutters at the mark where the copper pads connect.
Cut eight strips of the same length.

Prepare the NeoPixel Strips

Grab your utility knife or scissors. Starting at the end of the NeoPixel Strip without the test wires, cut the strip into eight segments, each having 20 individual NeoPixels. You will see cut lines marked between each double set of copper pads, which makes it easy.

At some point you will run across a factory solder point where you need to make a cut. Get your soldering iron to a nice hot temperature and de-solder the joint, using copper braid. Have patience, because these joints are even stronger than you think. You will need to pull gently as you operate the soldering iron in order to be successful.

Prepare the Wires

You will need quite a few wires for this project, so it's best to cut them now so you will be ready to solder. There are three different sizes of wire. Long wires will run down the entire length of the NeoPixel strips. Short wires which will be soldered in clusters of two on the strips in the center of the umbrella.

Now that you've double-checked the wires, go ahead and grab your snips and cut.
  • 7 long wires - 29" each (choose white or black to match your NeoPixel strip)
  • 6-7 short wires - 3 1/2" each (ground)
  • 6-7 short wires - 3 1/2" each (power)
Now would be a great time to prep both ends of the wires using a wire stripper (1/4").
These wire lengths were calculated based on the Totes Dome Umbrella. If you are using a different brand, or you are not sure if it is the identical Totes model, you should double check the lengths by measuring with a piece of string or measuring tape.

Solder the Wires

Take the short pieces of blue (ground) wire and gently twist the ends together as shown in the photo, then solder these connections. Repeat with the red (power) wires.

The strips are easiest to solder if you place them in a star-burst design with NeoPixels facing up on a large table. The directional arrows on all of the strips should start at the center and point outwards. Now, using a needle-nose pliers, carefully pull just a tiny bit of the LED strip out of its protective covering. That way you will be able to solder without melting the clear plastic.

Use the wired and sealed input end of one strip in your starburst and cut/strip the wires as shown.
Start with your blue wire chain and one of the black ground wires attached to your NeoPixel strip, if you've got one.

Solder the ground connections on each strip by tinning the pad with solder, then heating both the wire and pad to flow the solder together.

Repeat for all ground connections as shown.
Repeat the whole process for the power connections on each strip, daisy chaining them together with the wires you prepared earlier.
Solder one of your long wires to the first strip's input wire, and finish off with some heat shrink tubing. This wire will extend to the FLORA.

Now we will do a reverse move on the clear weatherproof covers on the NeoPixel strips. Carefully use your pliers to pull the strips back under the cover. You will need to over pull it so the pads at the bottom of the strips become exposed. Then, solder the other end of each of the white wires onto the DO pads. Once this task is complete, you can again pull the weatherproof covers back into their correct place.

Connect the other end of this long wire to the data input on its neighboring strip, using the underside of the flex PCB so the wire doesn't bump shoulders with the power or ground.
When you're finished, your wire connections should appear as shown. Double check that your solder joints are secure before arranging the strips in parallel to prep for umbrella-fying.

Now that you have things soldered, it would be good to try another test with the strips. Remember that the USB is not powerful enough to light up the strips, so once you load the program, plug the battery in and then turn it on. You should get a vibrant display. If not, use your multimeter to troubleshoot the circuit.


Now it's time to prepare the umbrella.

Insert the Circuit

Prepare the Umbrella

You will notice that the umbrella comes coated with a powder type substance. This was done intentionally to keep the vinyl from sticking to itself when it opens. So, do yourself a favor and leave it there. :) If you have already washed it off, you may want to add a little baby powder.

Cut the threads holding the vinyl to the umbrella, if there is any, using small scissors.

Insert the Circuit

Place your umbrella on the floor and gently move the circuit into its dome, making sure the front of the NeoPixel strips face the floor.

Now, take one LED strip and move it into place under one of the arms of the umbrella. Repeat with the rest of the strips. Note that this is a particularly fiddly task because the strips will want to shift. You may want to use masking tape or binder clips to secure as you work your way around. If you used solid-core wire, you may find you have to bend the wires slightly at the hub to ensure that they fit correctly.

Secure the NeoPixel Strips

Next, we will make the strips secure by adding cable ties. Align the strip end to the end of the umbrella's rib and use just a few cable ties to preliminarily secure the strip. Be sure the ties don't cover any of the LEDs on the NeoPixel strip. Repeat this process on each rib. Leave each end of NeoPixel strip free from the umbrella, since we'll glue them later, once we know the circuit works.

Keep these strip ends away from the metal ribs, letting them hand freely for now, so they don't short out.

One of your strips is bound to have a connector end-- this is a great place to connect up FLORA. Solder the red wire to VBATT, the black wire to GND, and the white signal wire to D6.

On a spare piece of vinyl you've binder-clipped into the edge of the umbrella, use velcro tape to secure the battery and double sided tape to secure the FLORA.

Test that your NeoPixels are all working! You should still have the custom strandtest sketch on your FLORA from the last testing step, but double check your number of pixels and pixel data pin in case some/all of your pixels aren't lighting up. Remember that a standard USB port can't power this many pixels, so you should be testing with USB disconnected and battery power on.

Everything's on? Great! Now onto tidy everything up.

Finishing Touches

Now that you know your circuit works, it's time to seal up the ends of the NeoPixel strip. Not only does this help with weatherproofing your circuit, but it provides strain relief for the delicate soldered wires inside your morphing umbrella.

Use some Permatex 66B silicone adhesive to stick end caps on the strip ends and also wedge some inside the dome-side ends too. Wear gloves, have proper ventilation, and let dry for 24 hours.
After the glue is completely dry, use zipties to secure the strip ends inside the umbrella ribs.
Fold the extra vinyl hammock over the FLORA circuit and binder-clip in place. Squeeze the metal tabs to remove them, leaving the clip with a lower profile.
Load the following sketch in the Adafruit Arduino IDE. Requires the color sensor library and NeoPixel library.
#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <Adafruit_NeoPixel.h>
 
#define PIN 6
#define TPIXEL 160 //The total amount of pixel's/led's in your connected strip/stick (Default is 60)
 
int switchPin = 10; // switch is connected to pin 10
int val; // variable for reading the pin status
int val2;
int buttonState; // variable to hold the button state
int lightMode = 0; // how many times the button has been pressed
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(TPIXEL, PIN, NEO_GRB + NEO_KHZ800);
// our RGB -> eye-recognized gamma color
byte gammatable[256];
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
 
void setup() {
Serial.begin(9600); // Set up serial communication at 9600bps
pinMode(switchPin, INPUT_PULLUP); // Set the switch pin as input
pinMode(PIN, OUTPUT);
strip.setBrightness(80); //adjust brightness here
buttonState = digitalRead(switchPin); // read the initial state
strip.begin();
strip.show(); // Initialize all pixels to 'off'
if (tcs.begin()) {
Serial.println("Found sensor");
} else {
Serial.println("No TCS34725 found ... check your connections");
while (1); // halt!
}
// thanks PhilB for this gamma table!
// it helps convert RGB colors to what humans see
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
gammatable[i] = x;
//Serial.println(gammatable[i]);
}
for (int i=0; i<3; i++){ //this sequence flashes the first pixel three times as a countdown to the color reading.
strip.setPixelColor (0, strip.Color(188, 188, 188)); //white, but dimmer-- 255 for all three values makes it blinding!
strip.show();
delay(1000);
strip.setPixelColor (0, strip.Color(0, 0, 0));
strip.show();
delay(500);
}
uint16_t clear, red, green, blue;
 
tcs.setInterrupt(false); // turn on LED
 
delay(60); // takes 50ms to read
tcs.getRawData(&red, &green, &blue, &clear);
tcs.setInterrupt(true); // turn off LED
Serial.print("C:\t"); Serial.print(clear);
Serial.print("\tR:\t"); Serial.print(red);
Serial.print("\tG:\t"); Serial.print(green);
Serial.print("\tB:\t"); Serial.print(blue);
// Figure out some basic hex code for visualization
uint32_t sum = red;
sum += green;
sum += blue;
sum = clear;
float r, g, b;
r = red; r /= sum;
g = green; g /= sum;
b = blue; b /= sum;
r *= 256; g *= 256; b *= 256;
Serial.print("\t");
Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.print((int)b, HEX);
Serial.println();
 
Serial.print((int)r ); Serial.print(" "); Serial.print((int)g);Serial.print(" "); Serial.println((int)b );
 colorWipe(strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]), 0);
}
 
// 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(20);
  }
}
 
void loop(){
  //rain();
  val = digitalRead(switchPin); // read input value and store it in val
  delay (20);
  val2 = digitalRead(switchPin);
  if (val == val2) {
    if (val != buttonState && val==LOW) { // the button state has changed!
        if (lightMode == 0) {
          lightMode = 1;
        }
      else if (lightMode == 1) {
          lightMode = 2;
        }
      else if (lightMode == 2){
          lightMode = 3;
          //delay (20);
        }
      else if (lightMode == 3) {
          lightMode = 0;
        }
      }
    }

buttonState = val; // save the new state in our variable
if (lightMode == 0) {
strip.show();
}
if (lightMode == 1) {
rainbow(10);
delay(20);
}
if (lightMode == 2) {
rain();
delay(20);
}
if (lightMode == 3) {
rainbowCycle(10);
delay(20);
  }
}
// Rain Program
 
void rain() {
// Create an array of 20 raindrops
  const int count = 20;
  int pos[count];
// Set each rain drop at the starting gate.
// Signify by a position of -1
for( int i=0; i < count; i++) {
pos[i]=-1;
}
// Main loop. Keep looping until we've done
// enough "frames."
boolean done=false;
int counter = 0;
while(!done) {
// Start by turning all LEDs off:
for(int i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, 0);
 
// Loop for each rain drop
for( int i=0; i < count; i++) {
// If the drop is out of the starting gate,
// turn on the LED for it.
if( pos[i] >= 0 ) {
strip.setPixelColor(pos[i], strip.Color(0,0,127));
// Move the drop down one row
pos[i] -= 7;
// If we've fallen off the strip, but us back at the starting gate.
if( pos[i] < 0 )
pos[i]=-1;
}
// If this drop is at the starting gate, randomly
// see if we should start it falling.
if ( pos[i] == -1 && random(40) == 0 && counter < 380 ) {
// Pick one of the 6 starting spots to begin falling
pos[i] = 143-random(6);
}
strip.show();
delay(2);
}
 
}
}
//Rainbow Program
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);
  }
}

// Rainbow Cycle Program - Equally distributed
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) {
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);
}
}

Use it!

Okay, time to have some fun! Make sure your battery is hooked up and turn FLORA on. The first NeoPixel in the first strip will blink three times to warn you that FLORA is getting ready to read a color. Hold up the outside of the umbrella that has the color sensor right next to your fabric/item of choice. The color sensor will flash and then the color will be loaded into all the NeoPixels.
Hit the push button once on your FLORAbrella for a fun rainbow pattern. Hit the button again and you will have the rain pattern. You'll have to switch the power off and on again to go back to the color sensor mode.

Have fun and send us pics of your finished FLORAbrella!