element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum RGB LED strip code questions (Sparkfun Pro Micro, LPD8806)
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 1 reply
  • Subscribers 415 subscribers
  • Views 331 views
  • Users 0 members are here
Related

RGB LED strip code questions (Sparkfun Pro Micro, LPD8806)

e14 Contributor
e14 Contributor over 13 years ago

Hello everyone,

 

I've finally gotten the following code (mostly) working with my sparkfun pro micro, a 5m (160 pixel) led strip and a 5-position switch (yes, for a hula-hoop). Now I am wanting to add more cases (ie patterns) to the handlestrip() function. However, for the life of me, I cannot figure out how a few things work:

 

1) Does "tick" just continue to count up to 4,294,967,295 (because it is an unsigned long) and then stop? What is the point of this?

 

2) In handlestrip(case 3) below, does every pixel in the strip turn on when "tick" is a multiple of 100, and then off when "tick"/50 has a remainder of 1 (e.g. at 51; 101; 151; 201...)? Is there a better way to adjust the rate of "strobing?"

 

3) How would I implement the ledbeltkit functions found later in the code (colorwipe, colorchase, dither, larson scanner, etc.) into additional cases in handlestrip() while retaining the ability to cycle through colors?

 

4) Would it be possible to read the last color that was displayed on the strip/pixel and then display the opposite color? Or, would it be possible to do a strobe in predefined colors while still retaining the ability to cycle through colors? For example, when using one of the strobe functions, instead of turning one color on and off, I want it to strobe between two colors - one that comes from GetColor() and another that is predefined depending on what GetColor() returns. (So, anytime GetColor() returns red, the second strobe color will be yellow. Anytime GetColor() returns blue, the second strobe will be white.. etc.)

 

Thank you all in advance :D

 

        //All credit for this code goes to Philihp at philihp.com/.../

        #include "LPD8806.h"
        #include "SPI.h"
        #include <avr/sleep.h>
        #include "carrot.h"

        //since data is on 11 and clock is on 13, we can use hardware SPI
        LPD8806 strip = LPD8806(160);


        int powerPin = 4;
        int upModePin = 3;
        int upColorPin = 2;

        int upModeButtonState = HIGH;
        int upModeButtonCycles = 0;
        int upColorButtonState = HIGH;
        int upColorButtonCycles = 0;

        int CYCLES_DEBOUNCE = 2; //check the button for X ticks to see if it is bouncing
        int MAX_COLORS = 8;
        int MAX_MODES = 8;
        int MAX_STRIPES = 5;

        unsigned long tick = 0;

        int mode = 1;
        int color = 1;

        uint16_t i, j, x, y;
        uint32_t c, d;

        // Set the first variable to the NUMBER of pixels. 32 = 32 pixels in a row
        // The LED strips are 32 LEDs per meter but you can extend/cut the strip

        void ISR_Wake() {
          detachInterrupt(0);
          detachInterrupt(1);
        }

        void blackout() {
          for(int i=0; i < strip.numPixels()+1; i++) {
            strip.setPixelColor(i, strip.Color(0,0,0));
          }
          strip.show();
        }


        void triggerSleep() {
          blackout();

          attachInterrupt(0,ISR_Wake,LOW); //pin 2
          attachInterrupt(1,ISR_Wake,LOW); //pin 3

          set_sleep_mode(SLEEP_MODE_PWR_DOWN);
          sleep_enable();
          sleep_mode();
          //sleeping, until rudely interrupted
          sleep_disable();
        }

        void triggerModeUp() {
          ++mode;
          blackout();
        }

        void triggerColorUp() {
          color++;
          blackout();
        }


        void handleButtons() {
          if(digitalRead(powerPin) == LOW) {
            triggerSleep();
          }
          // software debounce
          if(digitalRead(upModePin) != upModeButtonState) {
            upModeButtonCycles++;
            if(upModeButtonCycles > CYCLES_DEBOUNCE) {
              upModeButtonCycles = 0;
              upModeButtonState = digitalRead(upModePin);
              if(upModeButtonState == LOW) {
                triggerModeUp();
              }
            }
          }
          // software debounce
          if(digitalRead(upColorPin) != upColorButtonState) {
            upColorButtonCycles++;
            if(upColorButtonCycles > CYCLES_DEBOUNCE) {
              upColorButtonCycles = 0;
              upColorButtonState = digitalRead(upColorPin);
              if(upColorButtonState == LOW) {
                triggerColorUp();
              }
            }
          }
        }

        void handleStrip() {
          switch(mode%MAX_MODES) {
          case 0: //solid
            c = GetColor(color%MAX_COLORS);
            for(i=0; i<strip.numPixels(); i++) {
              strip.setPixelColor(i, c);
            }
            break;
          case 1: //solid
            c = GetColor((tick%3+color)% MAX_COLORS);
            for(i=0; i<strip.numPixels(); i++) {
              strip.setPixelColor(i, c);
            }
            break;
          case 2: //Strobe
            if(tick % 100 == 0) {
              c = GetColor(color%MAX_COLORS);
              for(i=0; i<strip.numPixels(); i++) {
                strip.setPixelColor(i, c);
              }
            }
            if(tick % 50 == 1) {
              c = strip.Color(0,0,0);
              for(i=0; i<strip.numPixels(); i++) {
                strip.setPixelColor(i, c);
              }
            }
            break;
        case 3: //Strobe modified
        j = tick % 384;
            if(tick % 100 == 0) {
              c = GetColor(color%MAX_COLORS);
              for(i=0; i<strip.numPixels(); i++) {
                strip.setPixelColor(i, c);
              }
            }
            if(tick % 50 == 1) {
              c = GetColor(color%MAX_COLORS);
              for(i=0; i<strip.numPixels(); i++) {
                strip.setPixelColor(i, Wheel(j));
              }
            }
            break;
          case 4: //chasers
            d = (color / MAX_COLORS) % MAX_STRIPES + 1; //chaser
            c = GetColor(color % MAX_COLORS); //color
            j = tick % (strip.numPixels()/d);
            for(i=0; i < strip.numPixels(); i++) {
              if(i % (strip.numPixels()/d) == j) {
                strip.setPixelColor(i, c);
              }
              else {
                strip.setPixelColor(i, strip.Color(0,0,0));
              }
            }
            break;
          case 5: //chasers + statics
            d = (color / MAX_COLORS) % MAX_STRIPES + 1; //chaser
            c = GetColor(color % MAX_COLORS); //color
            j = tick % (strip.numPixels()/d);
            for(i=0; i < strip.numPixels(); i++) {
              x = i % (strip.numPixels()/d);
              if((x == j) || (x == 0)) {
                strip.setPixelColor(i, c);
              }
              else {
                strip.setPixelColor(i, strip.Color(0,0,0));
              }
            }
            break;
          case 6: // rainbows
            j = tick % 384;
            for(i=0; i < strip.numPixels(); i++) {
              strip.setPixelColor(i, Wheel(((i * 384 / strip.numPixels() * (color%MAX_COLORS)) + j) % 384));
            }
            break;
          case 7: //carrot POV
            j = tick % 158;
            d = carrot[j];
            //green //orange
            c = (j < 30)?GetColor((color+2)%MAX_COLORS):GetColor((color+3)%MAX_COLORS);
            for(i=0;i<32;i++) {
              //adding 32 to the index makes it appear on the side opposite the controller
              if(d & 0x00000001) {
                strip.setPixelColor(i+32, c);
              }
              else {
                strip.setPixelColor(i+32, strip.Color(0,0,0));
              }
              d >>= 1;
            }
            break;
          /* case 7: //test
          int hiBit = 0;
          int n = strip.numPixels() - 1;
          for(i=0; i<strip.numPixels(); i++) {
          for(int bit=1; bit < 0x8000; bit <<= 1) {
            if(n & bit) hiBit = bit;
          }

          int bit, reverse;
          for(int i=0; i<(hiBit << 1); i++) {
            // Reverse the bits in i to create ordered dither:
            reverse = 0;
            for(bit=1; bit <= hiBit; bit <<= 1) {
              reverse <<= 1;
              if(i & bit) reverse |= 1;
            }
            strip.setPixelColor(reverse, c);
            strip.show();
            delay(500);
          }
          delay(250); // Hold image for 1/4 sec
        }
        
          break; */
          }

          strip.setPixelColor(strip.numPixels()-1, strip.Color(0,0,0)); //set that last LED off because it overlaps
          strip.show();
        }

        void setup() {
          // Start up the LED strip
          strip.begin();

          pinMode(powerPin, INPUT); // declare pushbutton as input
          pinMode(upModePin, INPUT); // declare pushbutton as input
          pinMode(upColorPin, INPUT); // declare pushbutton as input

          triggerSleep();
        }

        void loop() {
          tick++;
          handleStrip();
          handleButtons();
        }

        // fill the dots one after the other with said color
        // good for testing purposes
        void colorWipe(uint32_t c, uint8_t wait) {
          int i;

          for (i=0; i < strip.numPixels(); i++) {
              strip.setPixelColor(i, c);
              strip.show();
              delay(wait);
          }
        }

        // Chase a dot down the strip
        // good for testing purposes
        void colorChase(uint32_t c, uint8_t wait) {
          int i;

          for (i=0; i < strip.numPixels(); i++) {
            strip.setPixelColor(i, 0); // turn all pixels off
          }

          for (i=0; i < strip.numPixels(); i++) {
              strip.setPixelColor(i, c); // set one pixel
              strip.show(); // refresh strip display
              delay(wait); // hold image for a moment
              strip.setPixelColor(i, 0); // erase pixel (but don't refresh yet)
          }
          strip.show(); // for last erased pixel
        }

        // An "ordered dither" fills every pixel in a sequence that looks
        // sparkly and almost random, but actually follows a specific order.
        void dither(uint32_t c, uint8_t wait) {

          // Determine highest bit needed to represent pixel index
          int hiBit = 0;
          int n = strip.numPixels() - 1;
          for(int bit=1; bit < 0x8000; bit <<= 1) {
            if(n & bit) hiBit = bit;
          }

          int bit, reverse;
          for(int i=0; i<(hiBit << 1); i++) {
            // Reverse the bits in i to create ordered dither:
            reverse = 0;
            for(bit=1; bit <= hiBit; bit <<= 1) {
              reverse <<= 1;
              if(i & bit) reverse |= 1;
            }
            strip.setPixelColor(reverse, c);
            strip.show();
            delay(wait);
          }
          delay(250); // Hold image for 1/4 sec
        }

        // "Larson scanner" = Cylon/KITT bouncing light effect
        void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
          int i, j, pos, dir;

          pos = 0;
          dir = 1;

          for(i=0; i<((strip.numPixels()-1) * 8); i++) {
            // Draw 5 pixels centered on pos. setPixelColor() will clip
            // any pixels off the ends of the strip, no worries there.
            // we'll make the colors dimmer at the edges for a nice pulse
            // look
            strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4));
            strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2));
            strip.setPixelColor(pos, strip.Color(r, g, b));
            strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2));
            strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4));

            strip.show();
            delay(wait);
            // If we wanted to be sneaky we could erase just the tail end
            // pixel, but it's much easier just to erase the whole thing
            // and draw a new one next time.
            for(j=-2; j<= 2; j++)
                strip.setPixelColor(pos+j, strip.Color(0,0,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;
            }
          }
        }

        // Sine wave effect
        #define PI 3.14159265
        void wave(uint32_t c, int cycles, uint8_t wait) {
          float y;
          byte r, g, b, r2, g2, b2;

          // Need to decompose color into its r, g, b elements
          g = (c >> 16) & 0x7f;
          r = (c >> 8) & 0x7f;
          b = c & 0x7f;

          for(int x=0; x<(strip.numPixels()*5); x++)
          {
            for(int i=0; i<strip.numPixels(); i++) {
              y = sin(PI * (float)cycles * (float)(x + i) / (float)strip.numPixels());
              if(y >= 0.0) {
                // Peaks of sine wave are white
                y = 1.0 - y; // Translate Y to 0.0 (top) to 1.0 (center)
                r2 = 127 - (byte)((float)(127 - r) * y);
                g2 = 127 - (byte)((float)(127 - g) * y);
                b2 = 127 - (byte)((float)(127 - b) * y);
              } else {
                // Troughs of sine wave are black
                y += 1.0; // Translate Y to 0.0 (bottom) to 1.0 (center)
                r2 = (byte)((float)r * y);
                g2 = (byte)((float)g * y);
                b2 = (byte)((float)b * y);
              }
              strip.setPixelColor(i, r2, g2, b2);
            }
            strip.show();
            delay(wait);
          }
        }

        /* Helper functions */

        //Input a value 0 to 384 to get a color value.
        //The colours are a transition r - g - b - back to r

        uint32_t Wheel(uint16_t WheelPos)
        {
          byte r, g, b;
          switch(WheelPos / 128)
          {
          case 0:
            r = 127 - WheelPos % 128; // red down
            g = WheelPos % 128; // green up
            b = 0; // blue off
            break;
          case 1:
            g = 127 - WheelPos % 128; // green down
            b = WheelPos % 128; // blue up
            r = 0; // red off
            break;
          case 2:
            b = 127 - WheelPos % 128; // blue down
            r = WheelPos % 128; // red up
            g = 0; // green off
            break;
          }
          return(strip.Color(r,g,b));
        }


        uint32_t GetColor(int c)
        {
          switch(c) {
          case 0:
            return strip.Color(127,0,0);
          case 1:
            return strip.Color(0,0,127);
          case 2:
            return strip.Color(0,127,0);
          case 3:
            return strip.Color(127,31,0);
          case 4:
            return strip.Color(127,127,0);
          case 5:
            return strip.Color(0,127,127);
          case 6:
            return strip.Color(127,0,127);
          case 7:
            return strip.Color(127,127,127);
          default:
            return strip.Color(0,0,0);
          }
        }


  • Sign in to reply
  • Cancel
  • stipogill
    0 stipogill over 12 years ago

    The LPD8806 led strip are really interesting. Will work them with more new projects.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube